﻿using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using EnvDTE;
using EnvDTE80;
using Microsoft.Practices.RecipeFramework;
using ProjectBase.Guidance.Helpers;

namespace ProjectBase.Guidance.Actions
{
    public class AddAssemblyVersionAction : ConfigurableAction
    {
        public override void Execute()
        {
            CreateBaseVersion();
            CreateProjectVersion();
        }

        protected virtual void CreateProjectVersion()
        {
            var dte = GetService<DTE>(true);
            var dte2 = dte as DTE2;
            string source = Path.Combine(Path.GetDirectoryName(dte2.Solution.Properties.Item("Path").Value.ToString()),
                                         "Project");

            Trace.WriteLine("AssemblyVersion.cs reference whould be added");
            FileInfo f =
                new DirectoryInfo(source).GetFiles("AssemblyVersion.cs", SearchOption.AllDirectories).FirstOrDefault();

            if (f.Exists)
            {
                Trace.WriteLine("AssemblyVersion.cs found at " + f.FullName);

                AppendLinkAsProperty(dte, f.FullName, ProjectType.Entity);
                AppendLinkAsProperty(dte, f.FullName, ProjectType.Data);
                AppendLinkAsProperty(dte, f.FullName, ProjectType.Business);

                AppendLinkAsProperty(dte, f.FullName, ProjectType.Aop);

                AppendLinkAsProperty(dte, f.FullName, ProjectType.RestApi);
                AppendLinkAsProperty(dte, f.FullName, ProjectType.Mvc);
                AppendLinkAsProperty(dte, f.FullName, ProjectType.Web);

                AppendLinkAsProperty(dte, f.FullName, ProjectType.Tools);

                //AppendLinkAsProperty(dte, f.FullName, ProjectType.Test); // test should have own

                dte2.Documents.CloseAll(vsSaveChanges.vsSaveChangesNo);
            }
        }

        protected virtual void CreateBaseVersion()
        {
            string source = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
                                         @"Templates\Solutions\Core");
            if (Directory.Exists(source))
            {
                var dte = GetService<DTE>(true);
                var dte2 = dte as DTE2;
                string target =
                    Path.Combine(Path.GetDirectoryName(dte2.Solution.Properties.Item("Path").Value.ToString()), "Core");

                Project commonFolder = FindSolutionProject(dte2, "Core");

                foreach (string src in Directory.GetFiles(source))
                {
                    string dest = Path.Combine(target, Path.GetFileName(src));
                    File.Copy(src, dest);

                    commonFolder.ProjectItems.AddFromFile(dest);
                    if (src.Contains("AssemblyVersion"))
                    {
                        AppendLinkAsProperty(dte, dest, ProjectType.ProjectBase_Core);
                        AppendLinkAsProperty(dte, dest, ProjectType.ProjectBase_Data);
                        AppendLinkAsProperty(dte, dest, ProjectType.ProjectBase_Mvc);
                        AppendLinkAsProperty(dte, dest, ProjectType.ProjectBase_Tools);
                    }
                }
                dte2.Documents.CloseAll(vsSaveChanges.vsSaveChangesNo);
            }
        }

        protected virtual void AppendLinkAsProperty(DTE dte, string dest, ProjectType pType, int buildAction = 1)
        {
            Project prj = SolutionHelper.FindProject(dte, pType);
            ProjectItem prop = FindProperties(prj);
            ProjectItem pi = prop.ProjectItems.AddFromFile(dest);
            pi.Properties.Item("BuildAction").Value = buildAction;

            Trace.WriteLine("AssemblyVersion added to: " + prj.Name);
        }

        protected virtual Project FindSolutionProject(DTE2 dte2, string folderName)
        {
            var sol = dte2.Solution as Solution2;

            Project commonFolder = null;
            foreach (Project prj in (sol.Projects))
            {
                if (prj.Name == folderName)
                {
                    commonFolder = prj;
                }
            }
            return commonFolder;
        }

        protected virtual ProjectItem FindProperties(Project prj)
        {
            foreach (ProjectItem item in prj.ProjectItems)
            {
                if (item.Name == "Properties")
                {
                    return item;
                }
            }
            return null;
        }

        public override void Undo()
        {
        }
    }
}